package com.ae.shield.client.gui.util;

import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.client.renderer.texture.PotionSpriteUploader;
import net.minecraft.client.renderer.texture.Texture;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.fluid.Fluid;
import net.minecraft.inventory.container.PlayerContainer;
import net.minecraft.potion.Effect;
import net.minecraft.potion.EffectInstance;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import org.lwjgl.system.CallbackI;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

//TODO 将方法更改为使用GuiUtils和Screen的方法，并转为public static
public class GuiHelper {
    Screen gui;
    int xSize;
    int ySize;

    public GuiHelper(Screen gui, int xSize, int ySize) {
        this.gui = gui;
        this.xSize = xSize;
        this.ySize = ySize;
    }

    public boolean isMouseover(int mouseX, int mouseY, int x, int y, int width, int height) {
        int[] leftAndTop = guiLeftAndTop(gui, xSize, ySize);
        return mouseX > leftAndTop[0] + x && leftAndTop[0] + x + width > mouseX && mouseY > leftAndTop[1] + y && leftAndTop[1] + y + height > mouseY;
    }

    public int[] guiLeftAndTop(Screen gui, int guiXSize, int guiYSize) {
        return new int[]{(gui.width - guiXSize) / 2, (gui.height - guiYSize) / 2};
    }

    public FluidBar addFluidBar(IFluidHandler tank, int tankIndex) {
        return new FluidBar(tank, tankIndex, this);
    }

    /**
     * 用于处理流体储罐条的渲染
     */
    public class FluidBar {
        IFluidHandler tank;
        int index;
        final GuiHelper guiHelper;

        private FluidBar(IFluidHandler tank, int tankIndex, GuiHelper helper) {
            this.tank = tank;
            this.index = tankIndex;
            guiHelper = helper;
        }

        /**
         * 绘制给定流体
         *
         * @param x      绘制的位置x
         * @param y      绘制的位置y
         * @param width  宽度
         * @param height 高度
         */
        public void drawFluid(int x, float y, int width, int height) {
            FluidStack fluidStack = tank.getFluidInTank(index);
            Fluid fluid = fluidStack.getFluid();
            int[] leftAndUp = guiLeftAndTop(gui, xSize, ySize);
            int left = leftAndUp[0];
            int up = leftAndUp[1];
            if (!fluidStack.isEmpty()) {
                ResourceLocation location = fluid.getAttributes().getStillTexture(fluidStack);
                if (location != null) {
                    Minecraft mc = Minecraft.getInstance();
                    Texture texture = mc.getTextureManager().getTexture(PlayerContainer.LOCATION_BLOCKS_TEXTURE);
                    if (texture instanceof AtlasTexture) {
                        TextureAtlasSprite sprite = ((AtlasTexture) texture).getSprite(location);
                        mc.getTextureManager().bindTexture(PlayerContainer.LOCATION_BLOCKS_TEXTURE);
                        Color color = new Color(fluid.getAttributes().getColor());
                        drawTiledTexture(left + x, up + y, sprite, width, height, color);
                    }
                }
            }
        }

        public void drawFluidTip(int mouseX, int mouseY, int x, int y, int width, int height) {
            if (isMouseover(mouseX, mouseY, x - 1, y - 1, width + 1, height + 1)) {
                FluidStack fluidStack = tank.getFluidInTank(index);
                ITextComponent tip = new TranslationTextComponent("tooltip.ae.shield.fluid").append(new TranslationTextComponent("tooltip.ae.shield.empty"));
                if (!fluidStack.isEmpty()) {
                    ITextComponent count = new StringTextComponent(fluidStack.getAmount() + "/" + tank.getTankCapacity(index) + " ").mergeStyle(TextFormatting.BLUE);
                    tip = new TranslationTextComponent("tooltip.ae.shield.fluid", count).append(fluidStack.getDisplayName());
                }
                ArrayList<ITextComponent> list = new ArrayList();
                list.add(tip);
                gui.func_243308_b(new MatrixStack(), list, mouseX, mouseY);
            }
        }

        public GuiHelper getHelper() {
            return guiHelper;
        }
    }

    public void drawEffectIcon(EffectInstance effectInstance, int x, int y) {
        Minecraft mc = Minecraft.getInstance();
        int[] border = guiLeftAndTop(gui, xSize, ySize);
        Effect effect = effectInstance.getPotion();
        PotionSpriteUploader potionspriteuploader = Objects.requireNonNull(mc).getPotionSpriteUploader();
        TextureAtlasSprite textureatlassprite = potionspriteuploader.getSprite(effect);
        mc.getTextureManager().bindTexture(textureatlassprite.getAtlasTexture().getTextureLocation());
        AbstractGui.blit(new MatrixStack(), border[0] + x, border[1] + y, 0, textureatlassprite.getWidth(), textureatlassprite.getHeight(), textureatlassprite);
    }

    public void drawEffectTip(EffectInstance effectInstance, int mouseX, int mouseY, int x, int y, int width, int height) {
        if (isMouseover(mouseX, mouseY, x, y, width, height)) {
            Effect effect = effectInstance.getPotion();
            TranslationTextComponent name = (TranslationTextComponent) effect.getDisplayName();
            name.append(new StringTextComponent(" " + (effectInstance.getAmplifier() + 1))).append(new TranslationTextComponent("tooltip.ae.shield.level"));
            ArrayList<ITextComponent> list = new ArrayList<>();
            list.add(name);
            gui.func_243308_b(new MatrixStack(), list, mouseX, mouseY);
        }
    }

    public static Screen getGui() {
        return Minecraft.getInstance().currentScreen;
    }

    //参考了原版绘制与热力基本的流体绘制
    public void drawTiledTexture(int x, float y, TextureAtlasSprite icon, int width, int height, Color color) {

        int drawHeight;
        int drawWidth;

        for (int i = 0; i < width; i += 16) {
            for (int j = 0; j < height; j += 16) {
                drawWidth = Math.min(width - i, 16);
                drawHeight = Math.min(height - j, 16);
                drawFormSprite(x + i, y + j, icon, drawWidth, drawHeight, color);
            }
        }
    }

    //参考了原版绘制与热力基本的流体绘制
    public void drawFormSprite(int x, float y, TextureAtlasSprite sprite, int width, int height, Color color) {
        if (sprite == null) {
            return;
        }

        float minU = sprite.getMinU();
        float maxU = sprite.getMaxU();
        float minV = sprite.getMinV();
        float maxV = sprite.getMaxV();

        float u = minU + (maxU - minU) * width / 16F;
        float v = minV + (maxV - minV) * height / 16F;

        BufferBuilder bufferbuilder = Tessellator.getInstance().getBuffer();
        bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX);
        bufferbuilder.color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha())
                .pos(x, y + height, 0)
                .tex(minU, v).endVertex();
        bufferbuilder.color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha())
                .pos(x + width, y + height, 0)
                .tex(u, v).endVertex();
        bufferbuilder.color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha())
                .pos(x + width, y, 0)
                .tex(u, minV).endVertex();
        bufferbuilder.color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha())
                .pos(x, y, 0).tex(minU, minV)
                .endVertex();
        Tessellator.getInstance().draw();
    }
}
